package cn.com.xiaoshoujia.order.service.impl;

import cn.com.xiaoshoujia.activities.activity.ActivitiesActivity;
import cn.com.xiaoshoujia.activities.dto.*;
import cn.com.xiaoshoujia.activities.exception.ActivityException;
import cn.com.xiaoshoujia.activities.service.ActivitiesJoinService;
import cn.com.xiaoshoujia.application.service.WalletService;
import cn.com.xiaoshoujia.constants.*;
import cn.com.xiaoshoujia.domain.dto.FundsPoolTransactionDetailsDTO;
import cn.com.xiaoshoujia.domain.dto.SettlementDTO;
import cn.com.xiaoshoujia.domain.dto.WalletLogsDTO;
import cn.com.xiaoshoujia.domain.dto.WalletTransactionDetailsDTO;
import cn.com.xiaoshoujia.infrastructure.utils.Result;
import cn.com.xiaoshoujia.order.activity.OrderActivity;
import cn.com.xiaoshoujia.order.entity.Order;
import cn.com.xiaoshoujia.order.service.OrderService;
import cn.com.xiaoshoujia.wallet.activity.WalletActivity;
import cn.com.xiaoshoujia.wallet.entity.SettlementError;
import cn.com.xiaoshoujia.wallet.entity.WxpayMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {

    Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private OrderActivity orderActivity;

    @Autowired
    private ActivitiesJoinService activitiesJoinService;

    @Autowired
    private ActivitiesActivity activitiesActivity;

    @Autowired
    private WalletService walletService;

    @Autowired
    WalletActivity walletActivity;

    @Override
    public boolean save(Order order) {
        return orderActivity.save(order);
    }

    /**
     * @Author: dulei
     * @Description: 单买插入订单
     * @Date: 2017/8/6 14:47
     */
    @Transactional
    public ActivityOrderJoinDTO saveSingleOrder(ActivityOrderWxDTO wxOrder, Long productId) throws RuntimeException {
        return null;
    }

    /**
     * @Author: dulei
     * @Description: 开团下订单
     * @Date: 2017/8/6 15:09
     */
    @Transactional
    public ActivityOrderJoinDTO saveHeadOrder(ActivityOrderWxDTO wxOrder, Long productId) {
        return null;
    }

    /**
     * @Author: dulei
     * @Description: 参团
     * @Date: 2017/8/6 19:51
     */
    @Transactional
    public ActivityOrderJoinDTO saveJoinOrder(ActivityOrderWxDTO wxOrder, Long productId) {
        return null;
    }

    @Override
    public Integer findWxHeadStatus(Long headId) {
        return orderActivity.findWxHeadStatus(headId);
    }

    /**
     * @Author: yangrui
     * @Description:1 单买，2 团长开团，3 参团
     * @Date: 下午3:03 2017/8/30
     */
    @Transactional
    public boolean saveTeamOrder(ActivityOrderWxDTO wxOrder, Long productId) throws RuntimeException {
        if (wxOrder.getType().intValue() == 1) {
            return orderActivity.saveSingleOrder(wxOrder, productId);
        } else if (wxOrder.getType().intValue() == 2) {
            return orderActivity.saveHeadOrder(wxOrder, productId);
        } else if (wxOrder.getType().intValue() == 3) {
            return orderActivity.saveJoinOrder(wxOrder, productId);
        }
        return true;
    }

    @Override
    public Order findByOrderId(String orderId) {
        return orderActivity.findByOrderId(orderId);
    }

    public boolean notifyProcess(String orderId, String total_fee, String cluesId, String requestBody) {
        boolean flag = orderActivity.notifyProcess(orderId, total_fee, cluesId);
        if (flag) {
            //查询订单类型
            ActivityCluesMsgDTO activityCluesMsgDTO = orderActivity.findTypeByOrderId(orderId);
            if (null == activityCluesMsgDTO) {
                logger.error("未查到用户信息 msg = {},orderId = {}", activityCluesMsgDTO, orderId);
            } else {
                ActivitySmsMsgDTO smsMsg = activitiesActivity.findCSmsMsg(activityCluesMsgDTO.getActivitiesId());
                List<WalletLogsDTO> walletLogsList = walletService.findWalletLogsByOrderId(orderId);
                if (walletLogsList == null) {
                    throw new ActivityException("回调，下单时，钱包服务无响应,orderId:"+orderId);
                }
                //是否有正确的钱包日志
                boolean isHaveWalletLog = false;
                if (activityCluesMsgDTO.getType().intValue() == 1) {
                        for (WalletLogsDTO walletLogsDTO : walletLogsList) {
                            try {
                                //如果符合类型
                                if (walletLogsDTO.getBillingType().equals(BillingTypeEnum.INCOME.getCode())
                                    &&walletLogsDTO.getBusinessType().equals(BusinessTypeEnum.TRANSACTION.getCode())
                                    && walletLogsDTO.getFundsFrom().equals(FundsFromEnum.PERSONAL_WECHAT.getCode())
                                    && walletLogsDTO.getFundsTo().equals(FundsToEnum.BALANCE.getCode())
                                    && walletLogsDTO.getScene().equals(Scene.TEAM_SINGLE.getCode())){
                                    /*正常*/
                                    WalletTransactionDetailsDTO walletTransactionDetailsDTO = new WalletTransactionDetailsDTO();
                                    BeanUtils.copyProperties(walletLogsDTO, walletTransactionDetailsDTO);
                                    Result result = walletService.saveWalletTransactionDetails(walletTransactionDetailsDTO);
                                    /*乐观锁触发*/
                                    if ("FAIL".equals(result.getCode())) {
                                        logger.error("乐观锁触发");
                                        throw new ActivityException("回调，乐观锁触发");
                                    }

                                }
                            } catch (Exception e) {
                                logger.error(e.toString());
                                /*插入订单时断电，订单在全局异常日志中*/
                                saveWxPayMsg(orderId,requestBody);
                            }
                        }
                    //单买
                    activitiesJoinService.sendSingleMsg(smsMsg, activityCluesMsgDTO.getCluesPhone());
                } else if (activityCluesMsgDTO.getType().intValue() == 0) {
                        for (WalletLogsDTO walletLogsDTO : walletLogsList) {
                            try {
                                //如果符合类型
                                if (walletLogsDTO.getBillingType().equals(BillingTypeEnum.INCOME.getCode())
                                        &&walletLogsDTO.getBusinessType().equals(BusinessTypeEnum.TRANSACTION.getCode())
                                        && walletLogsDTO.getFundsFrom().equals(FundsFromEnum.PERSONAL_WECHAT.getCode())
                                        && walletLogsDTO.getFundsTo().equals(FundsToEnum.FUNDS_POOL.getCode())
                                        && walletLogsDTO.getScene().equals(Scene.TEAM_HEAD.getCode())) {
                                    /*正常*/
                                    FundsPoolTransactionDetailsDTO fundsPoolTransactionDetailsDTO = new FundsPoolTransactionDetailsDTO();
                                    BeanUtils.copyProperties(walletLogsDTO, fundsPoolTransactionDetailsDTO);
                                    Result result = walletService.saveFundsPoolTransactionDetails(fundsPoolTransactionDetailsDTO);
                                    /*乐观锁触发*/
                                    if ("FAIL".equals(result.getCode())) {
                                        logger.error("乐观锁触发");
                                        throw new ActivityException("回调，乐观锁触发");
                                    }
                                }
                            } catch (Exception e) {
                                logger.error(e.toString());
                                saveWxPayMsg(orderId,requestBody);
                            }
                        }
                    //拼团
                    ActivityHeadTimeDTO activityHeadTimeDTO = activitiesActivity.findTeamJoinMsg(activityCluesMsgDTO.getTeamId());
                    activitiesJoinService.sendTeamMsg(smsMsg, activityHeadTimeDTO.getTime(), activityCluesMsgDTO.getCluesPhone());
                    if (activityHeadTimeDTO.getPhones().size() > 0) {
                        Long teamId = activityCluesMsgDTO.getTeamId();
                        logger.debug("<<<<<<<<<<<<<<<<<<<<<<< wallet {} 已成功，待结算", teamId);
                        List<String> listOrderId = orderActivity.findByTeamId(teamId);
                        for (String str : listOrderId) {
                            logger.debug("<<<<<<<<<<<<<<<<<<<<<<< wallet 待结算 orderId {}", str);
                        }
                        SettlementDTO settlementDTO = new SettlementDTO();
                        settlementDTO.setOpeartor(activityCluesMsgDTO.getFkCompanyXcode());
                        settlementDTO.setOpeartorType(0);
                        settlementDTO.setFkCompanyXcode(activityCluesMsgDTO.getFkCompanyXcode());
                        settlementDTO.setScene(Scene.TEAM_HEAD_SUCCESS.getCode());
                        settlementDTO.setListOrderId(listOrderId);
                        logger.debug("钱包服务结算开始 fkCompanyXcode = {}", activityCluesMsgDTO.getFkCompanyXcode());
                        try {
                            Result result1 = walletService.settlement(settlementDTO);
                            logger.debug("钱包服务结算 result1 = {}", result1);
                            /*乐观锁触发*/
                            if ("FAIL".equals(result1.getCode())) {
                                for (String str : listOrderId) {
                                    SettlementError settlementError = new SettlementError();
                                    settlementError.setFkCompanyXcode(activityCluesMsgDTO.getFkCompanyXcode());
                                    settlementError.setOrderId(str);
                                    settlementError.setCreateTime(new Date());
                                    boolean aBoolean = walletActivity.settlementError(settlementError);
                                    if (!aBoolean) {
                                        logger.error("乐观锁触发");
                                    }
                                }
                            }
                        } catch (Exception e) {
                            logger.error("钱包服务结算异常", e.toString());
                            for (String str : listOrderId) {
                                SettlementError settlementError = new SettlementError();
                                settlementError.setOrderId(str);
                                settlementError.setFkCompanyXcode(activityCluesMsgDTO.getFkCompanyXcode());
                                settlementError.setCreateTime(new Date());
                                boolean aBoolean = walletActivity.settlementError(settlementError);
                                if (!aBoolean) {
                                    logger.error("保存钱包服务结算异常处理失败");
                                }
                            }
                        }
                        //团成功
                        for (String phone : activityHeadTimeDTO.getPhones()) {
                            activitiesJoinService.sendSuccessTeamSms(smsMsg, phone);
                        }
                    }
                } else {
                    logger.error("订单类型错误 orderId = {}", orderId);
                }

            }
        }
        return flag;
    }
    private void saveWxPayMsg(String orderId,String requestBody){
        /*插入订单时断电，订单在全局异常日志中*/
        WxpayMsg wxpayMsg = new WxpayMsg();
        wxpayMsg.setOrderId(orderId);
        wxpayMsg.setWxpayResponseMsg(requestBody);
        wxpayMsg.setCreateTime(new Date());
        boolean aBoolean1 = walletActivity.saveWxpayMsg(wxpayMsg);
        if (!aBoolean1) {
            logger.error("保存回调信息失败");
        }
    }

    @Transactional
    public boolean cancelOrder(String orderId) throws RuntimeException {
        return orderActivity.cancelOrder(orderId);
    }

    @Override
    public Map<String, Object> findNoPayOrder(String sysId, Long id) {
        return orderActivity.findNoPayOrder(sysId, id);
    }

}
